#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include "EstructurasPrueba.h"

#include <string.h>
#define modulo(x) ((x) < 0 ? - (x) : (x))

t_nodo * algoritmoCSCAN(t_nodo **, t_nodo **);
t_nodo * busquedaAlgoritmoCSCAN(t_nodo **, t_nodo **);
t_nodo * algoritmoSSTF(t_nodo **, t_nodo **);
t_nodo * busquedaAlgoritmoCSCAN (t_nodo **, t_nodo **);
void meterEnCola(t_nodo **, t_nodo **, long, char *, unsigned char, long);
int sacarDeCola(t_nodo **, t_nodo **);

extern t_chs CHS;

//Algoritmo de planificacion con inanicion

 t_nodo * algoritmoSSTF(t_nodo ** colaFte , t_nodo ** colaFin ){

     long minValue = 2147483647;
     t_nodo * ptr = *colaFte;
     t_nodo * ptrAux;
     long distancia;



     while (ptr) {


         if((distancia = modulo(ptr->pista - CHS.pista)) < minValue){
             minValue = distancia;
             ptrAux = ptr;
             ptr = ptr->siguiente;
         }
         else{
             ptr = ptr->siguiente;
         }

         ptr = *colaFte;

         while (ptr->siguiente != ptrAux){
             ptr = ptr->siguiente;
         }

         if (ptrAux->siguiente == NULL){
             ptr->siguiente = NULL;
             *colaFin = ptr;
         }
         else if (ptr == *colaFte){
             *colaFte = ptr->siguiente;
         }
         else {
         ptr->siguiente = ptrAux->siguiente;
         }

     }

     return ptrAux;
 }
//fin algoritmo SSTF
//Algoritmo de planificacion sin inanicion

 t_nodo * algoritmoCSCAN(t_nodo ** colaFte , t_nodo ** colaFin ){

  t_nodo * ptr, * ptrAnt = NULL;
  t_nodo * ptrMinTodos   = NULL;
  t_nodo * ptrMinMayores = NULL;
  t_nodo * ptrMinTodosAnt =  NULL;
  t_nodo * ptrMinMayoresAnt = NULL;
  long minTodos   = 2147483647;
  long minMayores = 2147483647;

  for(ptr = *colaFte; ptr; ptrAnt = ptr, ptr = ptr -> siguiente){
         if (ptr->pista < minTodos) {
                 minTodos = ptr->pista;
                 ptrMinTodos = ptr;
                 ptrMinTodosAnt = ptrAnt;
         }
         if (ptr->pista < CHS.pista) continue;
         if (ptr->pista < minMayores) {
                 minMayores = ptr->pista;
                 ptrMinMayores = ptr;
                 ptrMinMayoresAnt = ptrAnt;
         }
 }

 if (ptrMinMayores) {
         ptr = ptrMinMayores;
         ptrAnt = ptrMinMayoresAnt;
 } else {
         ptr = ptrMinTodos;
         ptrAnt = ptrMinTodosAnt;
 }

 if (ptrAnt == NULL) {
         *colaFte = ptr->siguiente;
         if (*colaFte == NULL) *colaFin = NULL;
 } else {
         ptrAnt -> siguiente = ptr -> siguiente;
         if (ptr -> siguiente == NULL) *colaFin = ptrAnt;
 }

 return ptr;

 }


 t_nodo * busquedaAlgoritmoCSCAN (t_nodo ** colaFte, t_nodo ** colaFin){

   t_nodo * ptr = NULL;
   t_nodo * ptrMinTodos   = NULL;
   t_nodo * ptrMinMayores = NULL;
   long minTodos   = 2147483647;
   long minMayores = 2147483647;

   for(ptr = *colaFte; ptr; ptr = ptr -> siguiente){
          if (ptr->pista < minTodos) {
                  minTodos = ptr->pista;
                  ptrMinTodos = ptr;
          }
          if (ptr->pista < CHS.pista) continue;
          if (ptr->pista < minMayores) {
                  minMayores = ptr->pista;
                  ptrMinMayores = ptr;
          }
  }

  if (ptrMinMayores) ptr = ptrMinMayores; else ptr = ptrMinTodos;

  return ptr;
 }


//fin algoritmo cscan

void meterEnCola(t_nodo ** colaFte, t_nodo ** colaFin, long nroSector, char * datosSector, unsigned char tipo, long pista) {

     t_nodo * nuevoNodo = malloc(sizeof(t_nodo));

     if(!tipo){
     //tipo escribirSector;
     nuevoNodo->datos = malloc(512);
     memcpy(nuevoNodo -> datos, datosSector, 512);
     }else{
     //tipo leerSector;
     nuevoNodo->datos = NULL;
     }
     nuevoNodo->nroSector = nroSector;
     nuevoNodo->pista = pista;
     nuevoNodo -> siguiente = NULL;
     if (*colaFin)
       (*colaFin) -> siguiente = nuevoNodo;
     else
       *colaFte = nuevoNodo;
       *colaFin = nuevoNodo;
}

int sacarDeCola(t_nodo ** colaFte, t_nodo ** colaFin) {
     t_nodo * nodo = * colaFte;
     int valor;
     if (!nodo) return 0;
     *colaFte = nodo -> siguiente;
     if (!(*colaFte)) *colaFin = 0;
     valor = nodo->nroSector;
     free(nodo);
     return valor;
}
